/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;

import org.creativor.rayson.api.Protocol;
import org.creativor.rayson.client.proxy.ProxyManager;
import org.creativor.rayson.client.transport.ConnectionPool;
import org.creativor.rayson.client.transport.nio.NioListener;

/**
 * The underling client object of Rayson.
 * 
 * @author creativor
 */
class Client {
	private static Client singleTon = new Client();

	static Client getClient() {
		return singleTon;
	}

	private final ProxyManager proxyManager;
	private final AtomicBoolean initialized;

	private Client() {
		proxyManager = new ProxyManager();
		initialized = new AtomicBoolean(false);
	}

	<T extends Protocol> T createProxy(final InetSocketAddress serverAddr,
			final Class<T> protocol) {

		lazyInitialize();
		return proxyManager.getProxy(serverAddr, protocol);
	}

	/**
	 * Lazy initialize this client.
	 * 
	 * @throws RuntimeException
	 *             If failed to initialize the NIO listener.
	 */
	private void lazyInitialize() throws RuntimeException {
		if (initialized.compareAndSet(false, true)) {
			proxyManager.initialize();
			ConnectionPool.getPool().initialize();
			try {
				NioListener.getListener().initialize();
			} catch (final IOException e) {
				throw new RuntimeException("Failed to initialize NIO listener",
						e);
			}
		}
	}
}
